from flask_restplus import Namespace, Resource, fields
from flask import request
from app.models import db, User, Book, OwnBook, ShareRecord
import re
from werkzeug.security import generate_password_hash, check_password_hash
from .auth import auth

api = Namespace("user", description="用户资源类")

doc = {
    'description': '接口未开发',  # 描述
    'deprecated': True  # 是否废弃
}

# 用户信息
user = api.model('user', {
    'uid': fields.Integer,
})
doc1 = {
    'params': {'uid': '用户的id'},  # 参数
    'description': '用户的信息',  # 描述
    'responses': {404: 'page not found'},  # 响应
    'deprecated': False  # 是否废弃
}

# 更改密码
doc2 = {
    'params': {'uid': '用户的id', 'old_password': '旧密码', 'one_password': '新密码1', 'two_password': '新密码2'},  # 参数
    'description': '更改用户密码',  # 描述
    'responses': {404: 'page not found'},  # 响应
    'deprecated': False  # 是否废弃
}
modify = api.model('modify', {
    'old_password': fields.String,
    'one_password': fields.String,
    'two_password': fields.String,
})

# 用户注册
doc3 = {
    'params': {'nikename': '用户昵称', 'emaill': '用户邮箱', 'password': '用户密码'},
    'description': '用户的注册',  # 描述
    'responses': {404: 'page not found'},  # 响应
    'deprecated': False  # 是否废弃
}
register = api.model('register', {
    'nikename': fields.String,
    'email': fields.String,
    'password': fields.String,
})

# 用户所拥有图书
doc4 = {
    'params': {'uid': '用户的id'},
    'description': '用户所拥有的图书',  # 描述
    'responses': {404: 'page not found'},  # 响应
    'deprecated': False  # 是否废弃
}
have_book = api.model('have_book', {
    "uid": fields.Integer
})

# 用户赠书
doc5 = {
    'params': {'uid': '赠书者用户id'},
    'description': '查询哪个用户给我捐过书',  # 描述
    'responses': {404: 'page not found'},  # 响应
    'deprecated': False  # 是否废弃
}
give_book = api.model('give_book', {
    "uid": fields.Integer,
})


@api.route("/<int:uid>/")
class UserAPI(Resource):
    method_decorators = [auth.login_required]

    # 用户信息
    @api.expect(user)
    @api.doc(**doc1)
    @api.response(200, 'success', headers={'nikename': '用户名','email': '用户邮箱','password': '用户密码'})
    @api.response(403, 'forbidden', headers={'uid': '用户id错误'})
    def get(self, uid):
        user = User.query.get_or_404(uid)
        return {"nikename": user.nikename, "email": user.email, "password": user.password}

    # 更改密码
    @api.doc(**doc2)
    @api.expect(modify)
    @api.response(200, 'success', headers={'two_password': '新密码'})
    @api.response(403, 'forbidden', headers={'old_password': '旧密码错误', 'two_password': '新密码不一致'})
    def put(self, uid):
        # 用户uid
        user = User.query.get(uid)
        password = user.password
        # 三种密码
        old_password = request.json.get('old_password')
        one_password = request.json.get('one_password')
        two_password = request.json.get('two_password')
        # 新密码不能为空
        if one_password == None:
            return {'UserAPI': 'new_password_null'}
        # 新密码要一致
        if two_password != one_password:
            return {'UserAPI': 'new_password_error'}
        # 判断旧密码一致
        if not check_password_hash(password, old_password):
            return {'UserAPI': 'old_password_error'}
        # 新密码覆盖旧密码
        user.password = generate_password_hash(one_password)
        db.session.add(user)
        return {'UserAPI': 'password_update'}

    @api.doc(**doc)
    def delete(self, uid):
        return {"ApiNoUse": "Undevelop"}


@api.route("/")
class UserListAPI(Resource):
    @api.doc(**doc)
    def get(self):
        return {"ApiNoUse": "Undevelop"}

    # 用户的注册
    @api.expect(register)
    @api.doc(**doc3)
    @api.response(200, 'success', headers={'success': '注册成功'})
    @api.response(403, 'forbidden', headers={'nikename': '昵称重复', 'email': '邮箱重复'})
    def post(self):
        nikename = request.json.get("nikename")
        email = request.json.get("email")
        password = request.json.get("password")
        if User.query.filter_by(email=email).all():
            return {"Error": "email_exist"}
        if User.query.filter_by(nikename=nikename).all():
            return {"Error": "nikename_exist"}
        if nikename == None:
            return {"Error": "nikename_empty"}
        if email == None:
            return {"Error": "email_empty"}
        if password == None:
            return {"Error": "password_empty"}
        c = re.compile(r"^\w+@(\w+\.)+(com|cn|net|org)$")
        m = c.search(email)
        if not m:
            return {"Error": "emailformat_error"}
        password = generate_password_hash(password)
        db.session.add(User(nikename=nikename, email=email, password=password))
        return {"OperteSuccess": "success"}

# 查看用户所拥有的图书
@api.route("/mybook/")
class QueryOwnBook(Resource):
    @auth.login_required
    @api.expect(have_book)
    @api.response(200, 'success', headers={'book.name': '书名', 'book.ISBN': '书的ISBN', 'book.description': '书的简介'})
    @api.response(403, 'forbidden', headers={'uid': '用户id错误'})
    @api.doc(**doc4)
    def get(self):
        uid = request.json["user_id"]
        books = OwnBook.query.filter_by(uid=uid).all()
        booklist = []
        for b in books:
            book = Book.query.filter_by(id=b.bid).first()
            booklist.append({"书名": book.name, "ISBN": book.ISBN, "简介": book.description})
        return {"show": booklist}

# 谁给我捐过书
@api.route("/mybook/donators/")
class Donate(Resource):
    @auth.login_required
    @api.doc(**doc5)
    @api.expect(give_book)
    @api.response(200, 'success', headers={'u.send': '赠书人', 'u.bookname': '书籍'})
    @api.response(403, 'forbidden', headers={'uid': '用户id错误'})
    def get(self):
        uid = request.json["user_id"]
        user = User.query.filter_by(id=uid).first()
        donators = ShareRecord.query.filter_by(receive=user.nikename).all()
        donatorslist = []
        for u in donators:
            donatorslist.append({"赠送人": u.send, "书籍": u.bookname})
        return {"show": donatorslist}
